package com.googlecode.bip.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.sql.Timestamp;
import javax.naming.NamingException;
import com.googlecode.bip.entity.IQuestion;
import com.googlecode.bip.entity.IUser;
import com.googlecode.bip.entity.IUserValue;
import com.googlecode.bip.entity.IllegalValueException;
import com.googlecode.bip.entity.impl.EntityHelper;

/**
 * DAO for {@link IUserValue}
 */
public interface UserValueDAO extends Serializable
{
    /**
     * Find {@link IUserValue} in database
     * <p>
     * Note for implementation: (userdate must be normalized - see {@link EntityHelper#getNormalizedTimestamp(java.util.Date)})
     * </p>
     *
     * @param iduser       iduser for this UserValue
     * @param idquestion   idquestion for this UserValue
     * @param userdate     userdate for this UserValue
     * @return IUserValue according to keys, or null if not found
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IUserValue findUserValue(
           int          iduser,
           int          idquestion,
           Timestamp    userdate
           )
       throws NamingException, SQLException;

    /**
     * Find {@link IUserValue} in database or prepare a new one
     * <p>
     * Note for implementation: (userdate must be normalized - see {@link EntityHelper#getNormalizedTimestamp(java.util.Date)})
     * </p>
     *
     * @param iduser       iduser for this UserValue
     * @param idquestion   idquestion for this UserValue
     * @param userdate     {@link Timestamp} for this UserValue
     * @return IUserValue according to keys
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IUserValue getUserValue(
           int          iduser,
           int          idquestion,
           Timestamp    userdate
           )
       throws NamingException, SQLException;

    /**
     * Find {@link IUserValue} in database or prepare a new one (with no value)
     * <p>
     * Note for implementation: (userdate must be normalized - see {@link EntityHelper#getNormalizedTimestamp(java.util.Date)})
     * </p>
     *
     * @param iuser       {@link IUser} for this UserValue
     * @param iquestion   {@link IQuestion} for this UserValue
     * @param userdate    {@link Timestamp} for this UserValue
     * @return IUserValue according to keys
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IUserValue getUserValue(
            IUser        iuser,
            IQuestion    iquestion,
            Timestamp    userdate
            )
        throws NamingException, SQLException;

    /**
     * @deprecated use {@link #insertUserValue(IUser, IQuestion, Timestamp, int, String, boolean)
     */
    public IUserValue insertUserValue(
            IUser       user,
            IQuestion   question,
            Timestamp   date,
            int         value,
            String      comment
            )
        throws NamingException, SQLException, IllegalValueException;

    /**
     * Insert a new value for user
     *
     * @param user      {@link IUser} to use
     * @param question  {@link IQuestion} to use
     * @param userdate  {@link Timestamp} for answer.
     * @param value     Value to use, must be valid according to question
     * @param comment   Optional comment for answer (could be null or empty)
     * @param isPrivate Set to true if user want to keep this answer private.
     * @return new {@link IUserValue}
     * @throws NamingException if any
     * @throws SQLException if any
     * @throws IllegalValueException if parameters are inconsistent
     */
    public IUserValue insertUserValue(
            IUser       user,
            IQuestion   question,
            Timestamp   userdate,
            int         value,
            String      comment,
            boolean     isPrivate
            )
        throws NamingException, SQLException, IllegalValueException;

    /**
     * Delete {@link IUserValue}
     *
     * @param uservalue
     * @return
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public boolean deleteUserValue( IUserValue uservalue )
        throws NamingException, SQLException;

    /**
     * Delete {@link IUserValue}
     *
     * @param iduser
     * @param idquestion
     * @param userdate
     * @return true if no error during delete
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public boolean deleteUserValue(
        final int        iduser,
        final int        idquestion,
        final Timestamp  userdate
        ) throws NamingException, SQLException;

    /**
     * Insert or Update {@link IUserValue}
     *
     * @param uservalue {@link IUserValue} to insert or update
     * @return true if no error during insert or update.
     *
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public boolean updateUserValue( final IUserValue uservalue )
        throws NamingException, SQLException;

}
